package com.lahuan.rpc.protocol;

import com.lahuan.rpc.protocol.netty.client.ClientInvoker;
import com.lahuan.rpc.protocol.netty.server.NettyServer;
import com.lahuan.rpc.protocol.netty.server.ServerInvoker;
import lombok.SneakyThrows;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;

import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;


/**
 * @author lfy
 */
public class CustomProtocol extends AbstractProxyProtocol {

    int defaultPort = 7000;
    public CustomProtocol() {
        super();
    }

    @Override
    public int getDefaultPort() {
        return defaultPort;
    }

    @Override
    protected int getErrorCode(Throwable e) {
        return super.getErrorCode(e);
    }

    public static Map<String, String> toParamMap(String url) {
        Map<String, String> map = null;
        if (url != null && url.indexOf("&") > -1 && url.indexOf("=") > -1) {
            map = new HashMap<String, String>();
            String[] arrTemp = url.split("&");
            for (String str : arrTemp) {
                String[] qs = str.split("=");
                map.put(qs[0], qs[1]);
            }
        }
        return map;
    }



    @SneakyThrows
    @Override
    protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
        System.out.println("doExport");
//        Map<String, String> paramMap = toParamMap(url.toString());
//        Integer port = Integer.valueOf(paramMap.get("bind.port"));
        // 按dubbo的设计，是所有的服务共用一个端口
        // 这里的demo程序只有一个服务，简化成这样的写法
        Thread thread = new Thread(() -> {
            try {
                //自定义一个端口
                NettyServer.start(defaultPort, new ServerInvoker(impl, type));
            } catch (Exception e) {
                e.printStackTrace();
            }

        });

        thread.setDaemon(true);
        thread.start();
        return () -> {
            //这里猜测应该是用来关闭的回调事件
            System.out.println("doExport runable");
        };
    }

    @Override
    protected <T> T doRefer(Class<T> type, URL url) throws RpcException {
        System.out.println("doRefer");
        System.out.println("doRefer url" +url);
        Map<String, String> paramMap = toParamMap(url.toString());
        String host = paramMap.get("register.ip");
        //http://localhost:8080/
        //String targetUrl ="custom://"+host+":"+defaultPort;
        return (T) Proxy.newProxyInstance(type.getClassLoader(),
                new Class[]{type},new ClientInvoker<T>(type,host,defaultPort)         );
    }

    @Override
    public void destroy() {
        //netty会随着程序关闭而关闭，不需要做额外销毁操作
        super.destroy();
    }

}